import { $toast } from '@/components/toast';
import xhr from '@/utils/http';
const content = {
  message: '',
  lngLat: '',
  requestTimeStr: '',
  responseTimeStr: '',
  from: '',
};
class Messager {
  MESSAGE = {
    REQ_LOCATION: 'request',
    RES_LOCATION: 'response',
    RESET: 'reset',
  };

  TYPE = {
    SEND: 'send',
    RECEIVE: 'receive',
  };
  retryTime = 20;
  h5Interval;
  miniInterval;
  timing = 1000;

  h5Msg = async (type, content) => {
    let data = null;
    if (type === this.TYPE.SEND) {
      data = {
        type,
        content: {
          message: content.message,
          lngLat: content.lngLat,
          requestTimeStr: content.requestTimeStr,
          responseTimeStr: content.responseTimeStr,
        }
      }
    } else {
      data = {
        type
      }
    }
    const res = await xhr.request({
      url: `/sys/wechat/h5Msg?from=${content.from}`,
      method: 'post',
      data,
    });
    res.content;
    return res;
  };

  wait = (timing) => {
    console.log(timing);
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve();
      }, timing || this.timing);
    });
  };

  stop = () => {
    if (this.retryTime > 0) return;
    if (this.h5Interval) {
      clearInterval(this.h5Interval);
      this.h5Interval = null;
    }
    if (this.miniInterval) {
      clearInterval(this.miniInterval);
      this.miniInterval = null;
    }
    if (this.cancel)
      this.cancel();
    $toast({
      title: '错误',
      text: '获取地图定位失败，请重新进入页面',
      during: 2000,
      isShowButton: false,
    });
    this.reset();
  }

  getContent = res => {
    try {
      return res.data;
      // return JSON.stringify(res.data.content)
    } catch (error) { }
  };

  getTimestr = () => String(Date.now());

  reset = async () => {
    try {
      this.timing = 1000;
      console.log(this.timing);
    } catch (error) {
      console.error(error);
    }
  };

  requestLocation = async () => {
    let TIME_STR
    const receive = async (resolve, reject) => {
      let content
      debugger
      do {
        let res = await this.h5Msg(this.TYPE.RECEIVE, {
          from: 'h5'
        });

        content = this.getContent(res);
      } while (!content);
      if (content.message !== this.MESSAGE.RES_LOCATION) {
        console.log(content.message);
        console.log(this.MESSAGE.RES_LOCATION);
        console.error('===');
        return receive();
      }
      if (content.requestTimeStr === TIME_STR) {
        let s = Date.now();
        await request();
        await this.wait(1000)
        return receive();
      }
      return content;

    }

    const request = async () => {
      TIME_STR = this.getTimestr();
      debugger
      await this.h5Msg(this.TYPE.SEND, {
        message: this.MESSAGE.REQ_LOCATION,
        requestTimeStr: TIME_STR,
        from: 'h5'
      });
    }
    try {
      await request()
      const content = await receive();
      console.log(content);
      return content
    } catch (error) {
      console.error(error);
    }


    /* try {
      await this.h5Msg(this.TYPE.SEND, {
        message: this.MESSAGE.REQ_LOCATION,
        requestTimeStr: TIME_STR,
        from: 'h5'
      });
      this.timing = Date.now() - Number(TIME_STR) + 200;
      console.log(this.timing);
      let content = await reReceive();
      // let content = this.getContent(res);
      // if (!content) content = await reReceive();
      await this.h5Msg(this.TYPE.SEND, {
        message: this.MESSAGE.RESET,
        responseTimeStr: content.responseTimeStr,
        requestTimeStr: TIME_STR,
        from: 'h5'
      });
      return content.lngLat;
    } catch (error) {
      console.error(error);
      console.log(this.retryTime);
      if (this.retryTime < 0) {

        while (this.retryTime--) {
          await this.requestLocation();
          this.retryTime = 3;
          break;
        }
      }
    }; */
  }

  responseLocation = async getLocation => {
    const polling = async () => {
      return new Promise((resolve, reject) => {
        this.miniInterval = setInterval(async () => {
          try {
            let res = await this.h5Msg(this.TYPE.RECEIVE, {
              from: 'mini'
            });
            let content = this.getContent(res);
            if (
              content &&
              (content.message === this.MESSAGE.REQ_LOCATION ||
                content.message === this.MESSAGE.RESET)
            ) {
              if (this.miniInterval) {
                clearInterval(this.miniInterval);
                this.miniInterval = null;
              }
              resolve(content);
            }
          } catch (error) {
            this.reset();
            reject(error);
          }
        }, this.timing);
      });
    };

    try {
      let content = await polling();
      const TIME_STR = this.getTimestr();
      let lngLat = {};
      if (content.message === this.MESSAGE.REQ_LOCATION) {
        const requestTimeStr = content.requestTimeStr;
        await this.h5Msg(this.TYPE.SEND, {
          requestTimeStr,
          message: this.MESSAGE.RES_LOCATION,
          responseTimeStr: TIME_STR,
          lngLat,
          from: 'mini'
        });
        this.timing = Date.now() - Number(TIME_STR) + 200;
        this.responseLocation();
      }
      if (content.message === this.MESSAGE.RESET) {
        clearInterval(this.miniInterval);
        this.miniInterval = null;
        this.reset();
        this.responseLocation();
      }
    } catch (error) {
      console.error(error);
      while (!!this.retryTime--) {
        await this.responseLocation();
        this.retryTime = 3;
        break;
      }
    }
  };
}

export default Messager;
